From b90e8cfc36261d17f84b2040609d1708327bc90f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 3 May 2011 12:33:31 -0400 Subject: [PATCH] gtkdnd: Add API that takes GIcon This will be useful for me to port gnome-panel to gnome-menus 4, which uses GAppInfo, which in turn returns icon references as GIcon. https://bugzilla.gnome.org/show_bug.cgi?id=649295 --- docs/reference/gtk/gtk3-sections.txt | 2 + gtk/gtk.symbols | 2 + gtk/gtkdnd.c | 86 ++++++++++++++++++++++++++-- gtk/gtkdnd.h | 6 ++ gtk/gtkimage.c | 14 +++++ gtk/gtkimageprivate.h | 1 + 6 files changed, 107 insertions(+), 4 deletions(-) diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt index 69d4407145..96d5e552d3 100644 --- a/docs/reference/gtk/gtk3-sections.txt +++ b/docs/reference/gtk/gtk3-sections.txt @@ -5992,12 +5992,14 @@ gtk_drag_set_icon_pixbuf gtk_drag_set_icon_stock gtk_drag_set_icon_surface gtk_drag_set_icon_name +gtk_drag_set_icon_gicon gtk_drag_set_icon_default gtk_drag_check_threshold gtk_drag_source_set gtk_drag_source_set_icon_pixbuf gtk_drag_source_set_icon_stock gtk_drag_source_set_icon_name +gtk_drag_source_set_icon_gicon gtk_drag_source_unset gtk_drag_source_set_target_list gtk_drag_source_get_target_list diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 9fa22ceaaf..a855b89944 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -749,6 +749,7 @@ gtk_drag_get_source_widget gtk_drag_highlight gtk_drag_result_get_type G_GNUC_CONST gtk_drag_set_icon_default +gtk_drag_set_icon_gicon gtk_drag_set_icon_name gtk_drag_set_icon_pixbuf gtk_drag_set_icon_stock @@ -759,6 +760,7 @@ gtk_drag_source_add_text_targets gtk_drag_source_add_uri_targets gtk_drag_source_get_target_list gtk_drag_source_set +gtk_drag_source_set_icon_gicon gtk_drag_source_set_icon_name gtk_drag_source_set_icon_pixbuf gtk_drag_source_set_icon_stock diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index 3e960c98e2..4805a6fe18 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -101,6 +101,7 @@ struct _GtkDragSourceSite GtkImagePixbufData pixbuf; GtkImageStockData stock; GtkImageIconNameData name; + GtkImageGIconData gicon; } icon_data; /* Stored button press information to detect drag beginning */ @@ -2477,6 +2478,11 @@ gtk_drag_begin_internal (GtkWidget *widget, site->icon_data.name.icon_name, -2, -2); break; + case GTK_IMAGE_GICON: + gtk_drag_set_icon_gicon (context, + site->icon_data.gicon.icon, + -2, -2); + break; case GTK_IMAGE_EMPTY: default: g_assert_not_reached(); @@ -2830,6 +2836,9 @@ gtk_drag_source_unset_icon (GtkDragSourceSite *site) case GTK_IMAGE_ICON_NAME: g_free (site->icon_data.name.icon_name); break; + case GTK_IMAGE_GICON: + _gtk_image_gicon_data_clear (&(site->icon_data.gicon)); + break; default: g_assert_not_reached(); break; @@ -2919,6 +2928,34 @@ gtk_drag_source_set_icon_name (GtkWidget *widget, site->icon_data.name.icon_name = g_strdup (icon_name); } +/** + * gtk_drag_source_set_icon_gicon: (method) + * @widget: a #GtkWidget + * @icon: A #GIcon + * + * Sets the icon that will be used for drags from a particular source + * to @icon. See the docs for #GtkIconTheme for more details. + * + * Since: 3.2 + **/ +void +gtk_drag_source_set_icon_gicon (GtkWidget *widget, + GIcon *icon) +{ + GtkDragSourceSite *site; + + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (icon != NULL); + + site = g_object_get_data (G_OBJECT (widget), "gtk-site-data"); + g_return_if_fail (site != NULL); + + gtk_drag_source_unset_icon (site); + + site->icon_type = GTK_IMAGE_GICON; + site->icon_data.gicon.icon = g_object_ref (icon); +} + static void gtk_drag_get_icon (GtkDragSourceInfo *info, GtkWidget **icon_window, @@ -3375,15 +3412,46 @@ gtk_drag_set_icon_name (GdkDragContext *context, const gchar *icon_name, gint hot_x, gint hot_y) +{ + GIcon *icon; + + g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); + g_return_if_fail (icon_name != NULL); + + icon = g_themed_icon_new (icon_name); + gtk_drag_set_icon_gicon (context, icon, hot_x, hot_y); + g_object_unref (icon); +} + +/** + * gtk_drag_set_icon_gicon: + * @context: the context for a drag. (This must be called + * with a context for the source side of a drag) + * @icon: a #GIcon + * @hot_x: the X offset of the hotspot within the icon + * @hot_y: the Y offset of the hotspot within the icon + * + * Sets the icon for a given drag from the given @icon. See the + * documentation for gtk_drag_set_icon_name() for more details about + * using icons in drag and drop. + * + * Since: 3.2 + **/ +void +gtk_drag_set_icon_gicon (GdkDragContext *context, + GIcon *icon, + gint hot_x, + gint hot_y) { GdkScreen *screen; GtkSettings *settings; GtkIconTheme *icon_theme; + GtkIconInfo *icon_info; GdkPixbuf *pixbuf; gint width, height, icon_size; g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); - g_return_if_fail (icon_name != NULL); + g_return_if_fail (icon != NULL); screen = gdk_window_get_screen (gdk_drag_context_get_source_window (context)); g_return_if_fail (screen != NULL); @@ -3398,12 +3466,22 @@ gtk_drag_set_icon_name (GdkDragContext *context, icon_theme = gtk_icon_theme_get_for_screen (screen); - pixbuf = gtk_icon_theme_load_icon (icon_theme, icon_name, - icon_size, 0, NULL); + icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme, icon, icon_size, 0); + if (icon_info != NULL) + { + pixbuf = gtk_icon_info_load_icon (icon_info, NULL); + } + else + pixbuf = NULL; + if (pixbuf) set_icon_stock_pixbuf (context, NULL, pixbuf, hot_x, hot_y, FALSE); else - g_warning ("Cannot load drag icon from icon name %s", icon_name); + { + char *str = g_icon_to_string (icon); + g_warning ("Cannot load drag icon from GIcon '%s'", str); + g_free (str); + } } /** diff --git a/gtk/gtkdnd.h b/gtk/gtkdnd.h index a2dcab6a33..1a7afe7c72 100644 --- a/gtk/gtkdnd.h +++ b/gtk/gtkdnd.h @@ -155,6 +155,8 @@ void gtk_drag_source_set_icon_stock (GtkWidget *widget, const gchar *stock_id); void gtk_drag_source_set_icon_name (GtkWidget *widget, const gchar *icon_name); +void gtk_drag_source_set_icon_gicon (GtkWidget *widget, + GIcon *icon); /* There probably should be functions for setting the targets * as a GtkTargetList @@ -186,6 +188,10 @@ void gtk_drag_set_icon_name (GdkDragContext *context, const gchar *icon_name, gint hot_x, gint hot_y); +void gtk_drag_set_icon_gicon (GdkDragContext *context, + GIcon *icon, + gint hot_x, + gint hot_y); void gtk_drag_set_icon_default (GdkDragContext *context); diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c index a755635d80..c6ba2947e0 100644 --- a/gtk/gtkimage.c +++ b/gtk/gtkimage.c @@ -2040,6 +2040,20 @@ gtk_image_update_size (GtkImage *image, gtk_widget_queue_resize (widget); } +void +_gtk_image_gicon_data_clear (GtkImageGIconData *data) +{ + if (data->pixbuf) + { + g_object_unref (data->pixbuf); + data->pixbuf = NULL; + } + if (data->icon) + { + g_object_unref (data->icon); + data->icon = NULL; + } +} /** * gtk_image_set_pixel_size: diff --git a/gtk/gtkimageprivate.h b/gtk/gtkimageprivate.h index 81a340d0d7..440348d711 100644 --- a/gtk/gtkimageprivate.h +++ b/gtk/gtkimageprivate.h @@ -75,6 +75,7 @@ struct _GtkImageGIconData GdkPixbuf *pixbuf; }; +void _gtk_image_gicon_data_clear (GtkImageGIconData *data); G_END_DECLS -- 2.30.2